using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI.HtmlControls;
using System.Web;
using System.Web.UI;
using System.Globalization;
using System.Threading;

namespace FreeLancer.HRB.Core.Web.Controls
{
  /// <summary>
  /// All pages in the custom themes as well as pre-defined pages in the root
  /// must inherit from this class.
  /// </summary>
  public class WebBasePage : System.Web.UI.Page
  {
    /// <summary>
    /// Language ID
    /// </summary>
    protected int _languageId;

    protected override void OnInit(EventArgs e)
    {
      base.OnInit(e);
      if (Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName == "vi")
        _languageId = 1;
      else
        _languageId = 2;
    }

    /// <summary>
		/// Adds links and javascript to the HTML header tag.
		/// </summary>
    protected override void OnLoad(EventArgs e)
    {
      base.OnLoad(e);

      if (!Page.IsCallback && !Page.IsPostBack)
      {
        // Links
        AddGenericLink("contents", "Default", Utils.RelativeWebRoot + "Default.aspx");
        AddGenericLink("start", WebAppSettings.Instance.Name, Utils.RelativeWebRoot);

        AddMetaContentType();
        AddDefaultLanguages();

        AddLocalizationKeys();
        //AddJavaScriptInclude(Utils.RelativeWebRoot + "blog.js", true, true);

        //if (BlogSettings.Instance.EnableOpenSearch)
        //  AddGenericLink("application/opensearchdescription+xml", "search", BlogSettings.Instance.Name, Utils.AbsoluteWebRoot + "opensearch.axd");

        //if (!string.IsNullOrEmpty(WebAppSettings.Instance.HtmlHeader))
        //  AddCustomCodeToHead();

        //if (!string.IsNullOrEmpty(WebAppSettings.Instance.TrackingScript))
        //  AddTrackingScript();
      }

      if (User.IsInRole(WebAppSettings.Instance.AdministratorRole))
      {
        //AddJavaScriptInclude(Utils.RelativeWebRoot + "admin/widget.js", true, true);
        //AddStylesheetInclude(Utils.RelativeWebRoot + "admin/widget.css");
      }
    }

    /// <summary>
		/// Adds the localization keys to JavaScript for use globally.
		/// </summary>
    protected virtual void AddLocalizationKeys()
    {
      StringBuilder sb = new StringBuilder();
      sb.Append("function registerVariables(){");
      sb.AppendFormat("WebApp.webRoot='{0}';", Utils.RelativeWebRoot);
      //sb.AppendFormat("WebApp.i18n.hasRated='{0}';", Translate("youAlreadyRated").Replace("'", "\\'"));
      //sb.AppendFormat("WebApp.i18n.savingTheComment='{0}';", Translate("savingTheComment").Replace("'", "\\'"));
      //sb.AppendFormat("WebApp.i18n.comments='{0}';", Translate("comments").Replace("'", "\\'"));
      //sb.AppendFormat("WebApp.i18n.commentWasSaved='{0}';", Translate("commentWasSaved").Replace("'", "\\'"));
      //sb.AppendFormat("WebApp.i18n.commentWaitingModeration='{0}';", Translate("commentWaitingModeration").Replace("'", "\\'"));
      //sb.AppendFormat("WebApp.i18n.cancel='{0}';", Translate("cancel").Replace("'", "\\'"));
      //sb.AppendFormat("WebApp.i18n.filter='{0}';", Translate("filter").Replace("'", "\\'"));
      //sb.AppendFormat("WebApp.i18n.apmlDescription='{0}';", Translate("filterByApmlDescription").Replace("'", "\\'"));
      sb.Append("};");

      ClientScript.RegisterStartupScript(this.GetType(), "registerVariables", sb.ToString(), true);
    }

    /// <summary>
    /// Adds the content-type meta tag to the header.
    /// </summary>
    protected virtual void AddMetaContentType()
    {
      HtmlMeta meta = new HtmlMeta();
      meta.HttpEquiv = "content-type";
      meta.Content = Response.ContentType + "; charset=" + Response.ContentEncoding.HeaderName;
      Page.Header.Controls.Add(meta);
    }

    /// <summary>
    /// Adds the default stylesheet language
    /// </summary>
    protected virtual void AddDefaultLanguages()
    {
      Response.AppendHeader("Content-Style-Type", "text/css");
      Response.AppendHeader("Content-Script-Type", "text/javascript");
    }

    /// <summary>
    /// Add a meta tag to the page's header.
    /// </summary>
    protected virtual void AddMetaTag(string name, string value)
    {
      if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(value))
        return;

      HtmlMeta meta = new HtmlMeta();
      meta.Name = name;
      meta.Content = value;
      Page.Header.Controls.Add(meta);
    }

    /// <summary>
    /// Adds the generic link to the header.
    /// </summary>
    public virtual void AddGenericLink(string relation, string title, string href)
    {
      HtmlLink link = new HtmlLink();
      link.Attributes["rel"] = relation;
      link.Attributes["title"] = title;
      link.Attributes["href"] = href;
      Page.Header.Controls.Add(link);
    }

    /// <summary>
    /// Adds the generic link to the header.
    /// </summary>
    public virtual void AddGenericLink(string type, string relation, string title, string href)
    {
      HtmlLink link = new HtmlLink();
      link.Attributes["type"] = type;
      link.Attributes["rel"] = relation;
      link.Attributes["title"] = title;
      link.Attributes["href"] = href;
      Page.Header.Controls.Add(link);
    }

    /// <summary>
    /// Adds a JavaScript reference to the HTML head tag.
    /// </summary>
    public virtual void AddJavaScriptInclude(string url, bool placeInBottom, bool addDeferAttribute)
    {
      if (placeInBottom)
      {
        string script = "<script type=\"text/javascript\"" + (addDeferAttribute ? " defer=\"defer\"" : string.Empty) + " src=\"" + ResolveScriptUrl(url) + "\"></script>";
        ClientScript.RegisterStartupScript(GetType(), url.GetHashCode().ToString(), script);
      }
      else
      {
        HtmlGenericControl script = new HtmlGenericControl("script");
        script.Attributes["type"] = "text/javascript";
        script.Attributes["src"] = ResolveScriptUrl(url);
        if (addDeferAttribute)
        {
          script.Attributes["defer"] = "defer";
        }

        Page.Header.Controls.Add(script);
      }
    }

    /// <summary>
    /// Adds a Stylesheet reference to the HTML head tag.
    /// </summary>
    /// <param name="url">The relative URL.</param>
    public virtual void AddStylesheetInclude(string url)
    {
      HtmlLink link = new HtmlLink();
      link.Attributes["type"] = "text/css";
      link.Attributes["href"] = url;
      link.Attributes["rel"] = "stylesheet";
      Page.Header.Controls.Add(link);
    }

    /// <summary>
    /// Resolves the script URL.
    /// </summary>
    /// <param name="url">The URL.</param>
    /// <returns></returns>
    public virtual string ResolveScriptUrl(string url)
    {
      return Utils.RelativeWebRoot + "js.axd?path=" + HttpUtility.UrlEncode(url) + "&amp;v=" + WebAppSettings.Instance.Version();
    }

    /// <summary>
    /// Adds a JavaScript to the bottom of the page at runtime.    
    /// </summary>
    /// <remarks>
    /// You must add the script tags to the BlogSettings.Instance.TrackingScript.
    /// </remarks>
    protected virtual void AddTrackingScript()
    {
      ClientScript.RegisterStartupScript(this.GetType(), "tracking", "\n" + WebAppSettings.Instance.TrackingScript, false);
    }

    /// <summary>
    /// Adds code to the HTML head section.
    /// </summary>
    protected virtual void AddCustomCodeToHead()
    {
      string code = string.Format(CultureInfo.InvariantCulture, "{0}<!-- Start custom code -->{0}{1}{0}<!-- End custom code -->{0}", Environment.NewLine, WebAppSettings.Instance.HtmlHeader);
      LiteralControl control = new LiteralControl(code);
      Page.Header.Controls.Add(control);
    }

    /// <summary>
    /// Translates the specified string using the resource files
    /// </summary>
    public virtual string Translate(string text)
    {
      object resource = GetGlobalResourceObject("labels", text);
      if (resource != null)
        return resource.ToString();

      return string.Format("Missing Resource [{0}]", text);
    }

    /// <summary>
    /// Raises the <see cref="E:System.Web.UI.TemplateControl.Error"></see> event.
    /// </summary>
    /// <param name="e">An <see cref="T:System.EventArgs"></see> that contains the event data.</param>
    protected override void OnError(EventArgs e)
    {
      HttpContext ctx = HttpContext.Current;
      Exception exception = ctx.Server.GetLastError();

      if (exception != null && exception.Message.Contains("callback"))
      {
        // This is a robot spam attack so we send it a 404 status to make it go away.
        ctx.Response.StatusCode = 404;
        ctx.Server.ClearError();
        //Comment.OnSpamAttack();
      }

      base.OnError(e);
    }
  }
}
